<!DOCTYPE html>
<html>
<title>View transitions: ensure input targets document root while rendering is suppressed</title>
<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7797">
<link rel="author" href="mailto:bokan@chromium.org">

<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>

<style>
:root {
  /* Ensure clicks during the transition fall through the pseudo tree root to
   * real DOM */
  view-transition-name: none;
}

::view-transition {
  /* Ensure clicks during the transition fall through the pseudo tree root to
   * real DOM */
  pointer-events: none;
  width: 0;
  height: 0;
}

::view-transition-group(*) {
  animation-duration: 30s;
}

#clicktarget {
  width: 100px;
  height: 100px;
  background: red;
}

#transition {
  width: 100px;
  height: 100px;
  background: blue;
  contain: paint;
  view-transition-name: transitionElement;
}
</style>

<div id="clicktarget"></div>
<div id="transition"></div>

<script>
const target = document.getElementById("clicktarget");

async function sendAndWaitForClick() {
  return new Promise(async (resolve) => {

    function eventHandler(ev) {
      resolve(ev);
    }

    document.documentElement.addEventListener("click", eventHandler);

    await new test_driver.Actions()
             .setContext(window)
             .addPointer("mousePointer1", "mouse")
             .pointerMove(10, 10, {origin: 'viewport', sourceName: "mousePointer1"})
             .pointerDown({sourceName: "mousePointer1"})
             .pointerUp({sourceName: "mousePointer1"})
             .send();

    document.documentElement.removeEventListener("click", eventHandler);
  });
}

promise_test(async t => {
  assert_implements(document.startViewTransition, "Missing document.startViewTransition");
  assert_not_equals(target, null, "PRECONDITION: target element is valid");

  // Ensure input is initialized before blocking rendering.
  await new test_driver.Actions()
               .setContext(window)
               .addPointer("mousePointer1", "mouse")
               .pointerMove(0, 0, {origin: "viewport", sourceName: "mousePointer1"})
               .send();

  let clickEvent = null;

  let transition = document.startViewTransition(async () => {
    clickEvent = await sendAndWaitForClick();
  });

  await transition.ready;

  assert_equals(clickEvent.target, document.documentElement,
      "Events must target the transition root while render blocked");
  clickEvent = null;

  clickEvent = await sendAndWaitForClick();

  // This just ensures we're not passing the above check by accident.
  assert_equals(clickEvent.target, target,
      "During transition, event should hit real DOM");

}, "Input when rendering suppressed targets root");
</script>
